<template>
  <div class="page-table">
    <a-table :columns="columns" :data-source="data?.data" :loading="loading" :pagination="pagination"
             :scroll="{ x: 'max-content' }"
             bordered rowKey="id" size="middle" @change="handleTableChange">

      <template #bodyCell="{ record, column }">
        <!-- 操作列  -->
        <template v-for="(action, index) in rowToActions[record.id]" v-if="column.key === '_action'">
          <a-divider v-if="index !== 0" type="vertical"/>
          <component :is="actionComponentMapping[action.type]" :action="action"
                     :extra-params="actionExtraParams(record)" :selected-rows="[record]"
                     type="link" @change="loadData"/>
        </template>

        <template v-else>
          <!-- 空内容 -->
          <template v-if="lookupValue(record, column) == null">
            <span class="text-slate-300">{{ column.config?.emptyText ?? '无' }}</span>
          </template>
          <!-- 日期时间 -->
          <template v-else-if="column.type === 'datetime'">
            {{ lookupValue(record, column) }}
          </template>
          <!-- 枚举 -->
          <template v-else-if="column.type === 'enum'">
            <a-tag :color="column.config.constants[lookupValue(record, column)].color">
              {{ column.config.constants[lookupValue(record, column)].text }}
            </a-tag>
          </template>
          <!-- 自定义组件 -->
          <template v-else-if="column.type === 'component'">
            <component :is="column.config.component" :config="column.config" :row="record"/>
          </template>
          <template v-else-if="column.type === 'image'">
            <a-image :src="$files.resolve(lookupValue(record, column))"
                     :style="{height: column?.config?.height ?? 48}"/>
          </template>
          <template v-else-if="column.type === 'images'">
            <a-image v-for="item in lookupValue(record, column)" :src="$files.resolve(item)"
                     :style="{height: column?.config?.height ?? 48}"/>
          </template>
          <!-- 长文本 -->
          <template v-else-if="column.type === 'long-text'">
            <a-popover>
              <template #content>
                <div class="set-popper">
                  {{ lookupValue(record, column) }}
                </div>
              </template>
              <div class="set-content">
                {{ lookupValue(record, column).slice(0, 10) + '...' }}
              </div>
            </a-popover>
          </template>
          <!-- 普通文本 -->
          <template v-else>
            {{ lookupValue(record, column) }}
          </template>

          <!-- 额外组件 -->
          <component :is="column.config?.extra" v-if="column.config?.extra" :row="record"/>
        </template>
      </template>

      <template #summary>
        <a-table-summary fixed>
          <a-table-summary-row>
            <a-table-summary-cell v-for="(column, index) in summaryColumns" :align="column.align" :index="index">
              <span v-if="lookupValue(data?.summary, column) == null" class="text-slate-300">无</span>
              <span v-else>{{ lookupValue(data?.summary, column) }}</span>
            </a-table-summary-cell>
          </a-table-summary-row>
        </a-table-summary>
      </template>
    </a-table>
  </div>
</template>
<script lang="jsx" setup>
import dayjs from "dayjs";
import numeral from "numeral";
import {allowed} from "../profile.js";
import FormAction from "./actions/form-action.vue";
import ConfirmAction from "./actions/confirm-action.vue";
import TableAction from "./actions/table-action.vue";
import BlankAction from "./actions/blank-action.vue";
import UrlAction from "./actions/url-action.vue";
import DetailAction from "./actions/detail-action.vue";

const {config} = defineProps(['config']);

const {isLoading: loading, data, execute: load} = useApi({
  url: config.dataUrl,
  immediate: false
});

const rowToActions = computed(() => {
  console.log(data)
  return data.value?.data.reduce((prev, row) => {
    const actions = rowActions.value.filter(action => {
      if (!allowed(action.permission)) {
        return false;
      }
      if (action.visible === false) {
        return false;
      }
      if (typeof action.visible === 'function') {
        return action.visible({
          selectedRows: [row]
        });
      }
      return true;
    });
    if (actions.length > 0) {
      prev[row.id] = actions;

      hasChildren(prev, actions, row)
    }

    return prev;
  }, {});
});

const hasChildren = (prev, actions, row) => {
  if (row.children && Array.isArray(row.children) && row.children.length > 0) {
    row.children.map(item => {
      prev[item.id] = actions;
      hasChildren(prev, actions, item)

    })
  }
}

const showActionColumn = computed(() => {
  return rowToActions.value != null && Object.keys(rowToActions.value).length > 0;
});

const actionComponentMapping = {
  'form': FormAction,
  'confirm': ConfirmAction,
  'table': TableAction,
  'url': UrlAction,
  'detail': DetailAction,
  'blank': BlankAction,
};

const columns = computed(() => {
  const resovleColumn = column => {
    if (column.children != null) {
      return {
        ...column,
        children: column.children.map(column => resovleColumn(column))
      };
    }

    let columnTitle = column.title;
    if (column.config?.unit === '万') {
      columnTitle = columnTitle + '（万）';
    }
    return {
      ...column,
      title: columnTitle
    }
  };

  const columns = (config.columns ?? []).map(column => {
    return resovleColumn(column);
  });
  if (showActionColumn.value) {
    columns.push({
      key: '_action',
      title: '操作'
    });
  }
  return columns;
});

const summaryColumns = computed(() => {
  if (config.summary == null) {
    return [];
  }
  return columns.value.flatMap(column => {
    if (column.children != null) {
      return column.children;
    }
    return column;
  });
});

const lookupValue = (row, column) => {
  const key = column.key;
  const value = key.split('.').reduce((a, b) => a?.[b], row);
  if (value == null) {
    return value;
  }
  if (column.type === 'datetime') {
    const dayjsValue = Array.isArray(value) ? dayjs(new Date(
      value[0],
      value[1] - 1,
      value[2],
      value[3],
      value[4],
      value[5],
    )) : dayjs(value);
    if (dayjsValue.isValid()) {
      return dayjsValue.format(column.config?.format ?? 'YYYY-MM-DD HH:mm:ss');
    }
    return value;
  } else if (column.config?.format != null) {
    if (column.config.unit === '万') {
      return numeral(value / 10000)
        .format(column.config?.format) + ' 万';
    } else if (column.config.unit === '%') {
      return numeral(value * 100)
        .format(column.config?.format) + ' %';
    }
    return numeral(value).format(column.config?.format);
  } else if (column.type === 'images') {
    return value.split(',')
  }
  return value;
}

const rowActions = computed(() => {
  return config.rowActions ?? [];
});

const actionExtraParams = row => {
  return {
    id: row.id
  }
};

const pagination = reactive({
  pageSize: 10,
  total: 0,
  current: 1,
  showTotal: total => `共 ${total} 条`,
  showSizeChanger: true
});
const sort = ref(columns.value.filter(column => column.sorter).map(column => `${(column.defaultSortOrder === 'ascend' ? '' : '-')}${column.key}`));
const params = ref({});

const loadData = async ({params: _params, page} = {}) => {
  if (_params != null) {
    params.value = _params;
  }
  if (page != null) {
    pagination.current = page;
  }
  const {rows} = await load({
    data: {
      ...params.value,
      size: pagination.pageSize,
      page: pagination.current,
      sort: sort.value
    }
  });
  pagination.total = rows;
}

const handleTableChange = async (_pagination, filter, _sorter) => {
  sort.value = _sorter.order == null
    ? config.sorter?.defaultSort
    : (_sorter.order === 'ascend' ? '' : '-') + _sorter.columnKey;
  pagination.current = _pagination.current;
  pagination.pageSize = _pagination.pageSize;
  await loadData();
}

defineExpose({loadData});
</script>
